home *** CD-ROM | disk | FTP | other *** search
/ JCSM Shareware Collection 1993 November / JCSM Shareware Collection - 1993-11.iso / cl720 / mcomm55j.lzh / COMM.CPP < prev    next >
C/C++ Source or Header  |  1993-03-14  |  10KB  |  279 lines

  1.  
  2. /////////////////////////////////////////////////////////////////////////////
  3. //                                                                         //
  4. //  COMM.CPP -- source for common functions for MCOMM AsyncPort class for  //
  5. //    Zortech C++, Turbo C++, Borland C++, Microsoft C++.                  //
  6. //    Compiler specific code:  MK_FP, SPTR (true if NEAR data), farmalloc  //
  7. //                                                                         //
  8. //    Mike Dumdei,  6 Holly Lane,  Texarkana TX  75503    (c) 1989,1990    //
  9. //                                                                         //
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. #include "comm.hpp"
  13. #include <string.h>
  14. #include <stdlib.h>
  15. #include <dos.h>
  16.  
  17. #if defined(__TURBOC__)
  18.   #include <alloc.h>
  19. #endif
  20.  
  21. #if (__TURBOC__ || __ZTC__)
  22.   #define FARMALLOC farmalloc
  23.   #define FARFREE   farfree
  24. #else  // __MSC__
  25.   #include <malloc.h>
  26.   #define FARMALLOC _fmalloc
  27.   #define FARFREE   _ffree
  28. #endif
  29.  
  30. #if (__TINY__ || __SMALL__ || __MEDIUM__ || _M_I86TM || _M_I86SM || _M_I86MM)
  31.   #define SPTR 1
  32. #endif
  33.  
  34. #ifndef MK_FP
  35. static inline void far * MK_FP(unsigned int s, unsigned int o)
  36. {
  37.     return (void far *)(((unsigned long)(s) << 16) | (unsigned long)(o));
  38. }
  39. #endif
  40.  
  41. /////////////////////////////////////////
  42. //  Default ring buffer size variables //
  43. /////////////////////////////////////////
  44. int AsyncPort::DefRxBufSz = 1024;   // 1K receive buffer
  45. int AsyncPort::DefTxBufSz = 1024;   // 1K transmit buffer
  46. int AsyncPort::DefMemType = 0;      // default to NEAR, NZ to default to FAR
  47.  
  48. /////////////////////////////////////////
  49. //  Constructor - Simple               //
  50. //    Presets port variables to 0      //
  51. //://////////////////////////////////////
  52. AsyncPort::AsyncPort()
  53. {
  54.     memset((void *)this, '\0', sizeof(AsyncPort));
  55. }
  56.  
  57. /////////////////////////////////////////
  58. //  Constructor - Allocs ring buffers  //
  59. //    Presets port variables to 0      //
  60. //    Allocates ring buffers           //
  61. //://////////////////////////////////////
  62. AsyncPort::AsyncPort(int RxBufSz, int TxBufSz, int UseFarMem)
  63. {
  64.     memset((void *)this, '\0', sizeof(AsyncPort));
  65.     AllocBuffers(RxBufSz, TxBufSz, UseFarMem);
  66. }
  67.  
  68. /////////////////////////////////////////
  69. //  Destructor                         //
  70. //    If necessary, calls Close and    //
  71. //    frees ring buffer memory.        //
  72. //://////////////////////////////////////
  73. AsyncPort::~AsyncPort()
  74. {
  75.     if (HdlrUsed != '\0')           // true if port not closed yet
  76.         Close();
  77. }
  78.  
  79. /////////////////////////////////////////
  80. //  Open Port - Detailed parameters    //
  81. //    Initializes port for interrupt   //
  82. //    driven operation.  Allocates     //
  83. //    default ring buffers if memory   //
  84. //    has not already been allocated.  //
  85. //    If Open fails default buffers    //
  86. //    are automatically deallocated.   //
  87. //    User defined buffers are not     //
  88. //    automatically deallocated.       //
  89. //://////////////////////////////////////
  90. int AsyncPort::Open(int ComBase, int IRQNbr, int InterruptVctr, char *Params)
  91. {
  92.     int rval;
  93.     int defbuffers = 0;
  94.  
  95.     if (!RingSeg && !RingOfst)          // if ring buffers not allocated,
  96.     {                                   // use defaults
  97.         AllocBuffers(DefRxBufSz, DefTxBufSz, DefMemType);
  98.         defbuffers = 1;
  99.     }
  100.      // open the port
  101.     rval = async_open(this, ComBase, IRQNbr, InterruptVctr, Params);
  102.     if (rval != R_OK && defbuffers == 1)     // if port open failed & default
  103.         FreeBuffers();                       // buffers, free default buffers
  104.     return (rval);                      // return port open result
  105. }
  106.  
  107. /////////////////////////////////////////
  108. //  Open Port -  COM1/COM2 abbrev      //
  109. //    Short method to open either COM1 //
  110. //    or COM2.  Calls detailed Open    //
  111. //    after selecting port address,    //
  112. //    irq, and interrupt vector.       //
  113. //://////////////////////////////////////
  114. int AsyncPort::Open(int ComN, char *Params)
  115. {
  116.     int base, irq, vector;
  117.  
  118.     if (ComN == COM1)
  119.         base = 0x3f8, irq = IRQ4, vector = VCTR4;
  120.     else if (ComN == COM2)
  121.         base = 0x2f8, irq = IRQ3, vector = VCTR3;
  122.     else
  123.         return R_NOPORT;
  124.     return (Open(base, irq, vector, Params));
  125. }
  126.  
  127. /////////////////////////////////////////
  128. //  Close port - No parameters         //
  129. //    Resets port to the state it was  //
  130. //    in prior to being opened.  Frees //
  131. //    ring buffer memory.              //
  132. //://////////////////////////////////////
  133. int AsyncPort::Close()
  134. {
  135.     int rval = async_close(this);   // call low level function to close port
  136.     if (rval == R_OK)               // free ring buffer memory if closed OK
  137.         FreeBuffers();
  138.     return rval;
  139. }
  140.  
  141. /////////////////////////////////////////
  142. //  Close port - Force DTR/RTS         //
  143. //    Manipulates class variable that  //
  144. //    'remembers' initial port DTR or  //
  145. //    RTS setting then calls normal    //
  146. //    Close to close the port and free //
  147. //    ring buffer memory.              //
  148. //://////////////////////////////////////
  149. int AsyncPort::Close(int DTR, int RTS)
  150. {
  151.     if (DTR != 0)                   // if ZR, close with DTR in pre-open state
  152.     {
  153.         if (DTR > 0)                // if > ZR, force DTR to remain high
  154.             OldMCR |= B_DTR;
  155.         else
  156.             OldMCR &= ~B_DTR;       // if < ZR, force DTR to go low
  157.     }
  158.     if (RTS != 0)                   // if ZR, close with RTS in pre-open state
  159.     {
  160.         if (RTS > 0)                // if > ZR, force RTS to remain high
  161.             OldMCR |= B_RTS;
  162.         else
  163.             OldMCR &= ~B_RTS;       // if < ZR, force RTS to go low
  164.     }
  165.     return Close();
  166. }
  167.  
  168. /////////////////////////////////////////
  169. //  Set XON/XOFF trip levels           //
  170. //    Returns R_OK (0) if success, or  //
  171. //    NZ if invalid parameters.  The   //
  172. //    Xon/Xoff 'Levels' are for bytes  //
  173. //    free in the buffer, therefore,   //
  174. //    the XoffLevel must be less than  //
  175. //    the XonLevel.  The Repeat level  //
  176. //    is the number of bytes that will //
  177. //    be accepted after sending an     //
  178. //    Xoff before sending a 2nd Xoff.  //
  179. //://////////////////////////////////////
  180. int AsyncPort::XTrip(int XoffLevel, int XonLevel, int RepeatLevel)
  181. {
  182.     if (XoffLevel >= XonLevel)
  183.         return (-1);
  184.     XoffTrip = XoffLevel;
  185.     XonTrip = XonLevel;
  186.     XTxRptInit = RepeatLevel;
  187.     return 0;
  188. }
  189.  
  190. /////////////////////////////////////////
  191. //  Transmit a C style string          //
  192. //    Returns bytes left available in  //
  193. //    transmit ring buffer.            //
  194. //://////////////////////////////////////
  195. int AsyncPort::Tx(char *String)
  196. {
  197.     return (async_txblk(this, String, strlen(String)));
  198. }
  199.  
  200. /////////////////////////////////////////
  201. //  AllocBuffers                       //
  202. //    Function to allocate ring buffer //
  203. //    memory.  Returns 1 if success,   //
  204. //    0 if memory already allocated or //
  205. //    no memory available.             //
  206. //://////////////////////////////////////
  207. int AsyncPort::AllocBuffers(int RxBufSz, int TxBufSz, int UseFarMem)
  208. {
  209.     unsigned long memptr;
  210.     int memsize = RxBufSz + TxBufSz;
  211.  
  212.     if (RingSeg || RingOfst)
  213.         return 0;                   // don't alloc if already allocated
  214.  
  215. #if SPTR  ////////////////////////////////////
  216.           //  SMALL OR MEDIUM MEMORY MODEL  //
  217.           ////////////////////////////////////
  218.     if (UseFarMem != 0)
  219.     {                               // if ring buffers in FAR mem
  220.         memptr = (unsigned long)FARMALLOC(memsize);
  221.         Stat3 |= (char)B_FARBUFFER;
  222.     }
  223.     else                            // if ring buffers in NEAR mem
  224.         memptr = (unsigned long)(unsigned int)new char[memsize];
  225.  
  226. #else     /////////////////////////////////////
  227.           //  LARGE OR COMPACT MEMORY MODEL  //
  228.           /////////////////////////////////////
  229.     memptr = (unsigned long)new char[memsize];
  230.  
  231. #endif    ////////////////////////////////////
  232.           //    END MODEL SPECIFIC CODE     //
  233.           ////////////////////////////////////
  234.     RxSize = RxBufSz;               // receive buffer size
  235.     TxSize = TxBufSz;               // transmit buffer size
  236.     RingSeg = (int)(memptr >> 16);  // seg of allocated memory (0 if NEAR)
  237.     RingOfst = (int)memptr;         // offset of allocated memory
  238.     if (memptr == 0L)
  239.         return 0;                   // return 0 if no memory available
  240.     return 1;                       // return 1, had some memory
  241. }
  242.  
  243. /////////////////////////////////////////
  244. //  FreeBuffers                        //
  245. //    Function to release ring buffer  //
  246. //    memory.  Returns 1 if success,   //
  247. //    0 if port not closed or no mem-  //
  248. //    ory to free.                     //
  249. //://////////////////////////////////////
  250. int AsyncPort::FreeBuffers()
  251. {
  252.     if ((!RingSeg && !RingOfst) || (HdlrUsed != '\0'))
  253.         return 0;                   // exit if port busy or nothing to free
  254.  
  255. #if SPTR  ////////////////////////////////////
  256.           //  SMALL OR MEDIUM MEMORY MODEL  //
  257.           ////////////////////////////////////
  258.     if (Stat3 & (char)B_FARBUFFER)
  259.     {                               // if FAR memory was allocated
  260.         FARFREE(MK_FP(RingSeg, RingOfst));
  261.         Stat3 &= (char)~B_FARBUFFER;
  262.     }
  263.     else
  264.         delete (char *)RingOfst;    // if NEAR memory was allocated
  265.  
  266. #else     /////////////////////////////////////
  267.           //  LARGE OR COMPACT MEMORY MODEL  //
  268.           /////////////////////////////////////
  269.     delete MK_FP(RingSeg, RingOfst);
  270.  
  271. #endif    ////////////////////////////////////
  272.           //    END MODEL SPECIFIC CODE     //
  273.           ////////////////////////////////////
  274.     RingSeg = RingOfst = 0;         // show ring buffers not allocated
  275.     return 1;
  276. }
  277.  
  278.  
  279.